package com.jms.web.mvc.resource;

import com.jms.web.mvc.context.WebMvcContext;
import com.jms.web.mvc.thread.MvcThreadLocalContext;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 静态资源管理类，用于处理和缓存Web应用中的静态资源（如HTML、CSS、JS等）。
 * 提供资源的缓存机制、有效性校验以及资源读取功能。
 */
public class StaticResourceManagement {

    /**
     * 静态资源缓存映射表，使用线程安全的ConcurrentHashMap存储路径与资源内容的映射关系。
     */
    private final static Map<String, StaticResource> cache = new ConcurrentHashMap<>();

    /**
     * Web MVC上下文对象，用于获取静态资源缓存时间等配置信息。
     */
    private static WebMvcContext webMvcContext;

    /**
     * 清空当前所有已缓存的静态资源。
     */
    public static void flushCache() {
        cache.clear();
    }

    /**
     * 设置Web MVC上下文对象。
     *
     * @param webMvcContext Web MVC上下文实例
     */
    public static void setWebMvcContext(WebMvcContext webMvcContext) {
        StaticResourceManagement.webMvcContext = webMvcContext;
    }

    /**
     * 判断指定路径的静态资源是否有效（即是否存在于缓存中且未过期）。
     *
     * @param path 静态资源路径
     * @return 如果资源有效返回true，否则返回false
     */
    public static boolean isValidStaticResource(String path) {
        if (cache.containsKey(path)) {
            StaticResource resource = cache.get(path);
            // 检查资源是否在缓存有效期内
            if (System.currentTimeMillis() - resource.getCreateTime() < webMvcContext.getStaticResourceCacheTime()) {
                return true;
            }
            // 资源已过期，从缓存中移除
            cache.remove(path);
        }
        return false;
    }

    public static void getStaticResource(String path) {
        HttpServletResponse response = MvcThreadLocalContext.getResponse();
        getStaticResource(response, path);
    }

    /**
     * 获取并输出指定路径的静态资源到HTTP响应中。
     * 如果资源在缓存中且有效，则直接从缓存读取；否则从类路径加载资源并缓存。
     *
     * @param response   HTTP响应对象，用于向客户端输出资源内容
     * @param staticPath 静态资源路径
     */
    public static void getStaticResource(HttpServletResponse response, String staticPath) {
        try (PrintWriter printWriter = response.getWriter()) {
            if (isValidStaticResource(staticPath)) {
                // 从缓存中获取资源
                StaticResource staticResource = cache.get(staticPath);
                printWriter.write(staticResource.getResource());
            } else {
                // 获取静态资源输入流
                InputStream inputStream = StaticResourceManagement.class.getResourceAsStream(staticPath);
                if (inputStream != null) {
                    // 以字符形式读取静态资源内容
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                    StringBuilder content = new StringBuilder();
                    char[] bt = new char[1024];
                    while (bufferedReader.ready()) {
                        int index = bufferedReader.read(bt);
                        content.append(bt, 0, index);
                    }
                    bufferedReader.close();
                    printWriter.write(content.toString());
                    // 将读取的内容存入缓存
                    StaticResource staticResource = new StaticResource(System.currentTimeMillis(), staticPath, content.toString());
                    cache.put(staticPath, staticResource);
                } else {
                    // 找不到资源时设置HTTP状态码为404
                    response.setStatus(HttpServletResponse.SC_NOT_FOUND);
                }
            }
            printWriter.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
